/**
 * 
 */
package com.gr.staffpm.pages.admin.user;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.wicket.extensions.markup.html.form.palette.Palette;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.util.CollectionModel;
import org.apache.wicket.model.util.ListModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.validation.validator.EmailAddressValidator;
import org.joda.time.Instant;
import org.wicketstuff.annotation.mount.MountPath;
import org.wicketstuff.annotation.strategy.MountHybrid;

import com.gr.staffpm.StaffPMWebPage;
import com.gr.staffpm.datatypes.Group;
import com.gr.staffpm.datatypes.Role;
import com.gr.staffpm.datatypes.User;
import com.gr.staffpm.form.validation.PasswordInputValidator;
import com.gr.staffpm.model.StringModel;
import com.gr.staffpm.pages.behaviour.FocusOnLoadBehavior;
import com.gr.staffpm.pages.error.UnauthorizedPage;
import com.gr.staffpm.security.constants.StaffPMRoles;
import com.gr.staffpm.security.service.UserService;


/**
 * @author Graham Rhodes 4 Mar 2011 21:36:22
 */
@MountHybrid
@MountPath(path = "secure/admin/AddUser")
public class AddUserPage extends StaffPMWebPage {

    @SpringBean(name = "userService")
    private UserService userService;
    private final User newUser = new User();
    private Palette<Role> rolesPalette;
    private Palette<Group> groupsPalette;
    private final TextField<String> firstName = new TextField<String>("firstName", new StringModel(""));
    private final TextField<String> lastName = new TextField<String>("lastName", new StringModel(""));
    private final PasswordTextField pass = new PasswordTextField("pass", new StringModel(""));
    private final PasswordTextField passConf = new PasswordTextField("passConf", new StringModel(""));
    private final TextField<String> emailAddress = new TextField<String>("emailAddress", new StringModel(""));

    public AddUserPage() {

        //TODO Check create user permission
        if (SecurityUtils.getSubject().hasRole(StaffPMRoles.ADMIN)) {

            Form<User> form = new Form<User>("addUserForm") {

                private static final long serialVersionUID = 1L;

                @Override
                protected void onSubmit() {
                    AddUserPage.this.onSubmit();
                }
            };
            add(form);

            add(new FeedbackPanel("feedback"));

            firstName.setRequired(true);
            firstName.add(new FocusOnLoadBehavior());
            form.add(firstName);

            lastName.setRequired(true);
            form.add(lastName);

            pass.setResetPassword(false);
            pass.setRequired(true);
            form.add(pass);

            passConf.setResetPassword(false);
            passConf.setRequired(true);
            form.add(passConf);

            //Validate Passwords
            form.add(new PasswordInputValidator(pass, passConf));

            emailAddress.add(EmailAddressValidator.getInstance());
            emailAddress.setRequired(true);
            form.add(emailAddress);

            List<Role> roles = userService.getAllRoles();
            IChoiceRenderer<Role> roleRenderer = new ChoiceRenderer<Role>("role", "roleId");
            rolesPalette = new Palette<Role>("roles", new ListModel<Role>(new ArrayList<Role>()), new CollectionModel<Role>(roles), roleRenderer, 10, false);
            form.add(rolesPalette);

            List<Group> groups = userService.getAllGroups();
            IChoiceRenderer<Group> groupRenderer = new ChoiceRenderer<Group>("name", "groupId");
            groupsPalette = new Palette<Group>("groups", new ListModel<Group>(new ArrayList<Group>()), new CollectionModel<Group>(groups), groupRenderer, 10, false);
            form.add(groupsPalette);

            Button cancel = new Button("cancelButton") {

                private static final long serialVersionUID = 1L;

                @Override
                public void onSubmit() {
                    setResponsePage(AdminUsersPage.class);
                }

            };
            cancel.setDefaultFormProcessing(false);
            form.add(cancel);

        } else {
            setResponsePage(UnauthorizedPage.class);
        }

    }

    @SuppressWarnings("unchecked")
    protected void onSubmit() {
        User currUser = userService.getCurrentUser();

        newUser.setFirstName(firstName.getValue());
        newUser.setLastName(lastName.getValue());
        newUser.setPassword(new Sha256Hash(pass.getValue(), null, 1024).toBase64());
        newUser.setEmailAddress(emailAddress.getValue());
        newUser.setLastUpdated(new Instant().toDate());
        newUser.setUpdatedBy(currUser);
        newUser.setUsername(StringUtils.lowerCase(newUser.getFirstName().substring(0, 1) + newUser.getLastName()));
        newUser.setCreatedBy(currUser);
        newUser.setCreated(new Instant().toDate());
        newUser.getRoles().addAll((List<Role>) rolesPalette.getDefaultModelObject());
        newUser.getGroups().addAll((List<Group>) groupsPalette.getDefaultModelObject());

        if (!userService.checkUserExists(newUser))
            userService.addOrUpdateUser(newUser);
        else
            error("A user already exists with that username.");

        //Send user back to previous page
        setResponsePage(new AdminUsersPage("Successfully added user: " + newUser.getFullName()));
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.StaffPMWebPage#getTitle()
     */
    @Override
    public String getTitle() {
        return "Add User - StaffPM";
    }

}
